const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
const serve = require('koa-static');
const fs = require('fs').promises;
const path = require('path');
const { exec } = require('child_process');
const { promisify } = require('util');

const execAsync = promisify(exec);
const app = new Koa();
const router = new Router();

app.use(bodyParser());
app.use(serve(__dirname));

// IP 地址转换为整数
function ipToInt(ip) {
  const parts = ip.split('.');
  return parts.reduce((acc, part) => (acc << 8) + parseInt(part), 0) >>> 0;
}

// 验证 IP 地址格式
function isValidIp(ip) {
  const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  return ipRegex.test(ip);
}

// 主页路由
router.get('/', async (ctx) => {
  ctx.type = 'html';
  ctx.body = await fs.readFile(path.join(__dirname, 'index.html'), 'utf8');
});

// 添加 IP 到白名单
router.post('/api/whitelist/add', async (ctx) => {
  try {
    const { ip } = ctx.request.body;
    
    if (!ip || !isValidIp(ip)) {
      ctx.status = 400;
      ctx.body = { error: 'IP 地址格式不正确' };
      return;
    }
    
    // 第一步：IP 转换为 [int, int] 数组
    const ipInt = ipToInt(ip);
    const ipRange = [ipInt, ipInt];
    
    // 第二步：读取并更新 ip_white.json
    const whitelistPath = path.join(__dirname, 'ip_white.json');
    let whitelist = [];
    
    try {
      const fileContent = await fs.readFile(whitelistPath, 'utf8');
      whitelist = JSON.parse(fileContent);
    } catch (error) {
      if (error.code !== 'ENOENT') throw error;
    }
    
    // 检查是否已存在
    const exists = whitelist.some(range => range[0] === ipRange[0] && range[1] === ipRange[1]);
    if (exists) {
      ctx.status = 409;
      ctx.body = { error: 'IP 已存在于白名单中' };
      return;
    }
    
    whitelist.push(ipRange);
    await fs.writeFile(whitelistPath, JSON.stringify(whitelist, null, 2), 'utf8');
    
    // 第三步：重新加载 nginx
    try {
      await execAsync('nginx -s reload');
      console.log('Nginx 配置已重新加载');
    } catch (error) {
      console.error('Nginx 重新加载失败:', error.message);
    }
    
    ctx.body = {
      success: true,
      message: 'IP 已添加到白名单',
      data: { ip, ipInt, ipRange, totalCount: whitelist.length }
    };
    
  } catch (error) {
    console.error('添加白名单失败:', error);
    ctx.status = 500;
    ctx.body = { error: '服务器内部错误' };
  }
});

app.use(router.routes()).use(router.allowedMethods());

const PORT = 5600;
app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
  console.log(`API: POST /api/whitelist/add`);
}); 